package cn.wch.ch934xlib.assist;

import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import cn.wch.ch934xlib.chip.ChipParameterUtil;
import cn.wch.ch934xlib.utils.FormatUtil;
import cn.wch.ch934xlib.utils.LogUtil;

import static cn.wch.ch934xlib.chip.ChipParameterUtil.PORT_OFFSET;
import static cn.wch.ch934xlib.chip.ChipParameterUtil.REG_GPIO_IN;
import static cn.wch.ch934xlib.chip.ChipParameterUtil.REG_IIR_THR;

/**
 * 下发数据的辅助类，主要是处理缓冲区空标志
 */
public class WriteDataAssist {

    private HashMap<Integer, Boolean> flagMap=new HashMap<>();
    private final Lock lock=new ReentrantLock(true);

    public void init(int serialCount){
        for (int i = 0; i < serialCount; i++) {
            flagMap.put(i,true);
        }
    }

    public boolean waitReady(int serialNumber,long timeout){
        while (timeout-->0){
            if(queryState(serialNumber)){
                return true;
            }
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public void setState(byte[] stateArray,int length){
        if(stateArray==null || stateArray.length<0 || stateArray.length<length){
            return;
        }
        int len=Math.min(stateArray.length,length);
        if(len<2){
            LogUtil.d("response is too short");
            return;
        }
        for (int i=0;i<1;i++){
            int portnum=(stateArray[i] & 0x0f);
            byte reg_iir =stateArray[i+1];

            if (reg_iir >= ChipParameterUtil.REG_UART_MODE && reg_iir <= REG_GPIO_IN) {
                LogUtil.d("receive gpio response: "+FormatUtil.bytesToHexString(stateArray,length));

                if ((portnum >= PORT_OFFSET) || (portnum < 2 * PORT_OFFSET)) {
                    portnum -= PORT_OFFSET;
                    LogUtil.d("portnum is "+portnum);
                    if (reg_iir == REG_GPIO_IN) {
                        short t= (short) ((((stateArray[i + 3])  & 0x00ff) << 8) |((stateArray[i + 2]) & 0x00ff));
                        GPIOAssist.getInstance().autoSetGPIOValLin(t);
                        LogUtil.d("response get gpio value "+t);
                    }
                }
                i+=4;
                continue;
            }else if ((reg_iir & 0x0f) == REG_IIR_THR){

                if ((portnum >= PORT_OFFSET) || (portnum < 2 * PORT_OFFSET)) {
                    portnum -= PORT_OFFSET;
                    LogUtil.d("receive empty flag: "+portnum);
                    setState(portnum,true);
                }
                break;
            }

        }


//        for(int i=0;i<(len/3);i++){
//            if ((stateArray[i*3+1] & 0xff) == 0x02 && (stateArray[i*3+2] & 0xff) == 0x00) {
//                int comNo=(stateArray[i*3] & 0x0f);
//                setState(comNo-4,true);
//            }
//        }
    }

    public void setState(int serialNumber,boolean bufEmptyFlag){

        try {
            lock.lock();
            if(!flagMap.containsKey(serialNumber)){
                return;
            }
            LogUtil.d(String.format(Locale.getDefault(),"设置串口%d发送缓冲区空标志：%b",serialNumber,bufEmptyFlag));
            flagMap.put(serialNumber,bufEmptyFlag);
        }finally {
            lock.unlock();
        }
    }

    private boolean queryState(int serialNumber){
        try {
            lock.lock();
            if(!flagMap.containsKey(serialNumber)){
                return false;
            }
            return flagMap.get(serialNumber);
        }finally {
            lock.unlock();
        }
    }

    public void close(){
        flagMap.clear();
        flagMap=null;
    }

}
